import { ref, h, defineComponent, render, nextTick } from "vue";
import { ElDrawer, ElDialog, ElButton } from "element-plus";

import {
  PlusForm,
  type PlusColumn,
  type FieldValues
} from "plus-pro-components";

interface ComponentOptions {
  title?: string;
  formModel?: FieldValues;
  formSchema?: PlusColumn[];
  formRules?: Record<string, any>;
  customContent?: () => ReturnType<typeof h>;
  onSubmit?: (formModel: FieldValues) => void;
  beforeSubmit?: (formModel: FieldValues) => boolean | Promise<boolean>;
  onSubmitError?: (errors: any) => void;
  componentType?: "drawer" | "dialog";
  componentProps?: Record<string, any>;
}

const useProComponent = () => {
  const visible = ref(false);
  const formModel = ref<FieldValues>({});
  const formRef = ref<InstanceType<typeof PlusForm> | null>(null);
  let options: ComponentOptions | null = null;

  const handleFormSubmit = async () => {
    if (!options) return;
    try {
      if (options.beforeSubmit) {
        const proceed = await options.beforeSubmit(formModel.value);
        if (!proceed) return;
      }

      if (formRef.value) {
        const isValid = await new Promise<boolean>(resolve => {
          formRef.value?.handleSubmit(valid => resolve(valid));
        });

        if (isValid) {
          if (options.onSubmit) {
            options.onSubmit(formModel.value);
            formRef.value.handleReset();
          }
          visible.value = false;
        } else {
          console.error("Form validation failed");
        }
      } else {
        options.onSubmit?.(formModel.value);
        visible.value = false;
      }
    } catch (error) {
      console.error("Error during form submission", error);
      options.onSubmitError?.(error);
    }
  };

  const handleCancel = () => {
    visible.value = false;
  };

  const ProComponent = defineComponent({
    setup() {
      return () => {
        const Component =
          options?.componentType === "dialog" ? ElDialog : ElDrawer;
        return h(
          Component,
          {
            modelValue: visible.value,
            title: options?.title || "Pro Component",
            width: "50%",
            onClose: handleCancel,
            ...options?.componentProps
          },
          {
            default: () => [
              options?.formSchema?.length
                ? h(PlusForm, {
                    ref: formRef,
                    model: formModel.value,
                    columns: options.formSchema,
                    rules: options.formRules,
                    hasFooter: false,
                    onSubmit: model => {
                      options?.onSubmit?.(model);
                      formRef.value?.handleReset();
                      visible.value = false;
                    },
                    onSubmitError: options?.onSubmitError
                  })
                : null,
              options?.customContent ? options.customContent() : null,
              h("div", { style: "text-align: right; margin-top: 20px;" }, [
                h(
                  ElButton,
                  { onClick: handleCancel },
                  { default: () => "取消" }
                ),
                h(
                  ElButton,
                  {
                    type: "primary",
                    onClick: handleFormSubmit,
                    style: "margin-left: 8px;"
                  },
                  { default: () => "确认" }
                )
              ])
            ]
          }
        );
      };
    }
  });

  let container: HTMLElement | null = null;

  const openComponent = (opts: ComponentOptions) => {
    options = opts;
    formModel.value = opts.formModel || {};
    visible.value = true;

    nextTick(() => {
      if (!container) {
        container = document.createElement("div");
        document.body.appendChild(container);
      }
      render(h(ProComponent), container);
    });
  };

  return { openComponent };
};

export default useProComponent;
